Lua Scripting Tutorial (Beginner 4)
This tutorial is a continuation of Lua Scripting Tutorial (Beginner 3), which introduced the if-then-else statement in Lua, and the "recentbest" functions from the Foldit Lua Interface. The recipe used in this tutorial is Beginner Rebuild SCRIPT 4.01. The previous tutorials have involved basically the same recipe, which did a rebuild of the first 10 segments, followed by a shake and a wiggle. In this tutorial, we'll continue to extend the recipe, taking a big step toward making it more realistic. Instead of just rebuilding the first 10 segments, this version of the recipe will gradually rebuild the entire protein. This usually produces much better results, although it takes longer. New features This tutorial introduces a new Foldit function, structure.GetCount, which counts the segments in the protein. Once you know the number of segments, you can use a for loop to work on different spots. In Lua, there are at least three types of loop statements, which allow to perform a certain number of steps repeatedly. The "for" loop in its simplest form, is useful when you want to do something a fixed number of times. Other types of loop continue to repeat the steps until some condition is met. (This type of programming "loop" has nothing to do with the protein structure loops that receive a lot of attention in Foldit.) As in the other tutorials, start Foldit with beginner or a revisiting puzzle. Reset the puzzle if you've already played it for the other tutorials. It's probably best to shake and wiggle before using the recipe, but it's not required. Download the recipe above and open it in the Foldit recipe editor. As before, it's best to export the recipe and then use an external editor like Notepad++, but the Foldit editor will do. One more advantage of an external editor is that it's easier to compare this version of the recipe to the previous versions. Counting the protein Near the beginning of Beginner Rebuild SCRIPT 4.01, there are two new lines: segCnt = structure.GetCount () print ( "The protein has " .. segCnt .. " segments" ) The first line calls the Foldit Lua function structure.GetCount, which returns the number of segments in the protein. The segment count is stored in the variable "segCnt". The second line prints the segment count. This output will appear in the recipe output window. You can also find this information manually by hovering over the last segment in the protein and hitting the tab key. This opens the segment information window, which shows the segment number and other details about the segment. The only drawback is that it's generally hard to tell which end of the protein is which, so you'll probably pick segment 1 50% of the time. In most puzzles, the segment count is fixed, but many design puzzles let you add or delete segments. Once you know how big the protein is, it's easy to rebuild it in pieces. Rebuilding in pieces The previous versions of our recipe just rebuilt the first 10 segments of the protein. Doing just that much often improves the score, at least at the start of a puzzle. But it obviously leaves out the rest of the protein. In this version of the recipe, the main set of Foldit commands from the previous versions has been moved inside the new "for" loop. These statements will be repeated for many small sections of the protein. The for loop looks like this: buildLen = 3 for ii = 1, segCnt - buildLen + 1, buildLen do ....statements to be repeated.... end The variable "buildLen" represents how many segments will be rebuilt at a time. For this recipe, we'll try using a much shorter rebuild length, which tends to produce better results in the long run. The "for" statement is the actual start of the loop. In this version, there's an initial value, a maximum value, and an optional step or increment. The "ii" in this statement is just a variable name, often called the loop counter. The variable "ii" gets used inside the loop, which is one way that repeating the same statements can do different things. In this case, "1" is the initial value, which is generally a good place to start. The next part is the maximum value. When "ii" reaches this value, the loop ends, and the recipe goes on following the loop's "end" statement. The maximum expression is: segCnt - buildLen + 1 so if there are 97 segments, and the rebuild length is 3, the maximum is 97 - 3 + 1, or 95. The loop stops when the value of ii goes past 95. The final part of the for statement is the step or increment, which is the rebuild length, or 3 in this example. So ii starts out at 1, then goes to 4, 7, 10, and so on. Inside the loop (between the for and the end), most of the statements are the same as before. The most changed statement is the one which selects the segments to work on: selection.SelectRange ( ii, ii + buildLen - 1 ) Instead of using fixed values 1 and 10 as before, this statement is now based on ii, the loop counter. For example, if ii is 7 and buildLen is 3, segments 7 to 9 (7 + 3 - 1) are selected. There are a couple of other changes inside the loop. For one thing, each rebuild only goes for one cycle. That's really done to speed things up a bit. Rebuilding the whole protein this way takes a lot longer than rebuilding just 10 segments. There's also a new variable "loopScore", which records the score at the beginning of the loop. If a given rebuild doesn't improve on this score, the protein is set back to the recent best position, using recentbest.Restore. Wrapping Up Try running the new recipe if you haven't already. It's going to take a lot longer to run than the previous versions, because its doing a lot more work. Normally, it will find a much larger gain. If you get tired of watching it, minimize the Foldit window and come back in a little while. At this point, you'll probably see some things you could change. For one thing, you can try changing the rebuild length, by setting "buildLen" to a different value. Try setting buildLen = 1. The recipe should run more quickly, but it may not do much for your score. Starting with buildLen = 2 is probably a better idea. Another possible change is the number of rebuilds on structure.RebuildSelected. It's set to 1 in this recipe, but you can try larger values. The more rebuilds you ask for, the longer the recipe will run. Yet another change would be to rebuild in overlapping sections. Rebuilding segments 1 to 3 may work, and so may rebuilding 4 to 6. There's no reason to suspect that rebuilding 2 to 4 or 3 to 5 won't work as well, but this recipe doesn't try it. Try tinkering with the for statement to rebuild in overlapping segments. Lua Scripting Tutorial (Beginner 5) introduces an important new Lua feature: tables. Tables are probably Lua's most unique and powerful feature. Recipes use tables in many ways. One frequent use is to make a "work list", a table containing ranges of segments for the recipe to work on. The next tutorial will create a work list and use it to guide the rebuild process. See Lua Scripting Tutorial (Beginner 4 Tech Supplement) for more on the nitty-gritty of this tutorial. Category:Script tutorial